package com.example.tool.util;

import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.util.ObjectUtil;
import org.apache.commons.lang3.StringUtils;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.Duration;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.Calendar;
import java.util.Date;


public class DateUtil {
    private static final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    public static String convertTimestampToDateTime(long timestamp) {
        // 将 13 位时间戳转换为 Date
        Date date = new Date(timestamp);
        // 定义日期时间格式
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
        // 格式化 Date 为字符串
        return sdf.format(date);
    }

    public static String convertTimeStampToDateTimeV2(String timestamp) {
        if (StringUtils.isBlank(timestamp)) {
            return null;
        }
        return convertTimeStampToDateTimeV2(Long.parseLong(timestamp));
    }


    public static String convertTimeStampToDateTimeV2(Long timestamp) {
        // 将 13 位时间戳转换为 Date
        Date date = new Date(timestamp);
        // 定义日期时间格式
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        // 格式化 Date 为字符串
        return sdf.format(date);
    }

    /**
     * 时区 - 默认
     */
    public static final String TIME_ZONE_DEFAULT = "GMT+8";

    /**
     * 秒转换成毫秒
     */
    public static final long SECOND_MILLIS = 1000;

    public static final String FORMAT_YEAR_MONTH_DAY = "yyyy-MM-dd";

    public static final String FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND = "yyyy-MM-dd HH:mm:ss";

    /**
     * 将 LocalDateTime 转换成 Date
     *
     * @param date LocalDateTime
     * @return LocalDateTime
     */
    public static Date of(LocalDateTime date) {
        if (date == null) {
            return null;
        }
        // 将此日期时间与时区相结合以创建 ZonedDateTime
        ZonedDateTime zonedDateTime = date.atZone(ZoneId.systemDefault());
        // 本地时间线 LocalDateTime 到即时时间线 Instant 时间戳
        Instant instant = zonedDateTime.toInstant();
        // UTC时间(世界协调时间,UTC + 00:00)转北京(北京,UTC + 8:00)时间
        return Date.from(instant);
    }

    /**
     * 将 Date 转换成 LocalDateTime
     *
     * @param date Date
     * @return LocalDateTime
     */
    public static LocalDateTime of(Date date) {
        if (date == null) {
            return null;
        }
        // 转为时间戳
        Instant instant = date.toInstant();
        // UTC时间(世界协调时间,UTC + 00:00)转北京(北京,UTC + 8:00)时间
        return LocalDateTime.ofInstant(instant, ZoneId.systemDefault());
    }

    public static Date addTime(Duration duration) {
        return new Date(System.currentTimeMillis() + duration.toMillis());
    }

    public static boolean isExpired(LocalDateTime time) {
        LocalDateTime now = LocalDateTime.now();
        return now.isAfter(time);
    }

    /**
     * 创建指定时间
     *
     * @param year  年
     * @param mouth 月
     * @param day   日
     * @return 指定时间
     */
    public static Date buildTime(int year, int mouth, int day) {
        return buildTime(year, mouth, day, 0, 0, 0);
    }

    /**
     * 创建指定时间
     *
     * @param year   年
     * @param mouth  月
     * @param day    日
     * @param hour   小时
     * @param minute 分钟
     * @param second 秒
     * @return 指定时间
     */
    public static Date buildTime(int year, int mouth, int day,
                                 int hour, int minute, int second) {
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.YEAR, year);
        calendar.set(Calendar.MONTH, mouth - 1);
        calendar.set(Calendar.DAY_OF_MONTH, day);
        calendar.set(Calendar.HOUR_OF_DAY, hour);
        calendar.set(Calendar.MINUTE, minute);
        calendar.set(Calendar.SECOND, second);
        calendar.set(Calendar.MILLISECOND, 0); // 一般情况下，都是 0 毫秒
        return calendar.getTime();
    }

    public static Date max(Date a, Date b) {
        if (a == null) {
            return b;
        }
        if (b == null) {
            return a;
        }
        return a.compareTo(b) > 0 ? a : b;
    }

    public static LocalDateTime max(LocalDateTime a, LocalDateTime b) {
        if (a == null) {
            return b;
        }
        if (b == null) {
            return a;
        }
        return a.isAfter(b) ? a : b;
    }

    /**
     * 是否今天
     *
     * @param date 日期
     * @return 是否
     */
    public static boolean isToday(LocalDateTime date) {
        return LocalDateTimeUtil.isSameDay(date, LocalDateTime.now());
    }

    /**
     * 是否昨天
     *
     * @param date 日期
     * @return 是否
     */
    public static boolean isYesterday(LocalDateTime date) {
        return LocalDateTimeUtil.isSameDay(date, LocalDateTime.now().minusDays(1));
    }

    /**
     * 将给定日期加上指定天数
     *
     * @param date 给定的日期
     * @param days 要加的天数
     * @return 加上天数后的日期
     */
    public static Date addDays(Date date, int days) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.DAY_OF_MONTH, days);
        return calendar.getTime();
    }

    public static Date dateFormat(String dateStr, String simpleDateFormat) {
        try {
            return new SimpleDateFormat(simpleDateFormat).parse(dateStr);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }

    public static Date dateFormat(String dateStr) {
        return dateFormat(dateStr, FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND);
    }

    public static Date toDate(String dateStr) {
        if (StringUtils.isBlank(dateStr)) {
            return null;
        }
        sdf.setLenient(false); // 严格模式（禁止自动转换，如 "2023-02-30" 会报错）
        try {
            return sdf.parse(dateStr);
        } catch (ParseException e) {
            return new Date(Long.parseLong(dateStr));
        }
    }

    public static String toDateToStr(String dateStr) {
        if (StringUtils.isBlank(dateStr)) {
            return "";
        }
        sdf.setLenient(false); // 严格模式（禁止自动转换，如 "2023-02-30" 会报错）
        try {
            return dateToStr(sdf.parse(dateStr));
        } catch (ParseException e) {
            return dateToStr(new Date(Long.parseLong(dateStr)));
        }
    }

    public static String dateToStr(Date date) {
        if (ObjectUtil.isNull(date)) {
            return "";
        }
        return sdf.format(date);
    }

    /**
     * 加小时
     *
     * @param date 时间
     * @param hour 小时数
     * @return LocalDateTime
     */
    public static Date addHourDate(Date date, Integer hour) {
        if (date == null) {
            return null;
        }
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.HOUR_OF_DAY, hour);
        return calendar.getTime();
    }

    /**
     * 获取两个时间的时间差 date2-date1
     *
     * @param date1
     * @param date2
     * @return
     */
    public static Long findTimeDifference(Date date1, Date date2) {
        if (date1 == null || date2 == null) {
            return 0L;
        }
        // 计算毫秒差并转换为秒
        long millisecondsDifference = date2.getTime() - date1.getTime();
        return millisecondsDifference / 1000;
    }

    public static String convertDateToDateStr(Date date) {
        // 定义日期时间格式
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        // 格式化 Date 为字符串
        return sdf.format(date);
    }

    public static String convertDateToDateStr2(Date date) {
        // 定义日期时间格式
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        // 格式化 Date 为字符串
        return sdf.format(date);
    }
}
